import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:flutter/services.dart' show rootBundle;

///数据库支持 的 工具类
class Provider {
  static Database db;

  /// 获取数据库中所有的表
  Future<List> getTables() async {
    if (db == null) return Future.value([]);

    List tables =
        await db.rawQuery('SELECT name From sqlite_master WHERE type="table"');
    List<String> targetTables = [];

    tables.forEach((item) {
      targetTables.add(item['name']);
    });

    return targetTables;
  }

  ///初始化数据库
  Future init(bool isCreate) async {
    //create a db file,if db file not created
    //get a db-path
    String databasePath = await getDatabasesPath();
    String path = join(databasePath, 'flutter_demo.db');
    print(path);
    try {
      db = await openDatabase(path);
    } catch (e) {
      print('Error $e');
    }

    //check db is right
    bool tableIsRight = await checkTableIsRight();
    if (!tableIsRight) {
      //关闭上面打开的db,否则无法执行open
      db.close();
      //删除数据库
      await deleteDatabase(path);

      //将assets/app.db的内容，拷贝到上面的path下面
      ByteData data = await rootBundle.load(join("assets", "app.db"));
      print(
          'offsetInBytes--${data.offsetInBytes}, data.lengthInBytes--${data.lengthInBytes}');
      List<int> bytes =
          data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
      await new File(path).writeAsBytes(bytes);

      db = await openDatabase(path, version: 1,
          onCreate: (Database db, int version) async {
        print('db created version is $version');
      }, onOpen: (Database db) async {
        print('new db opened');
      });
    } else {
      print("Opening existing database");
    }
  }

  ///检查数据库中表是否完整，在部分android中，会出现表丢失情况
  Future<bool> checkTableIsRight() async {
    List<String> expectTables = ['cat', 'widget', 'collection'];
    List<String> table = await getTables();

    for (int i = 0; i < expectTables.length; i++) {
      if (!table.contains(expectTables[i])) {
        return false;
      }
    }
    return true;
  }
}
